#include "iam_rasterview.h"

/**
 * @brief Float32 栅格视角对象
 * 
 */
IAM_RasterView_F32 IAM_RasterView_init0_F32(void)
{
    IAM_RasterView_F32 view = malloc(sizeof(_IAM_RasterView_F32));
    view->m_size_x = 0;
    view->m_size_y = 0;
    view->m_pdata = NULL;
    view->m_nodata = nanf("");
    return view;
}

IAM_RasterView_F32 IAM_RasterView_init_F32(size_t size_x, size_t size_y, float* pdata)
{
    IAM_RasterView_F32 view = malloc(sizeof(_IAM_RasterView_F32));
    view->m_size_x = size_x;
    view->m_size_y = size_y;
    view->m_pdata = pdata;
    view->m_nodata = nanf("");
    return view;
}

void IAM_RasterView_reset_F32(IAM_RasterView_F32 view, size_t size_x, size_t size_y, float * pdata)
{
    view->m_size_x = size_x;
    view->m_size_y = size_y;
    view->m_pdata = pdata;
    view->m_nodata = nanf("");
}

void IAM_RasterView_release_F32(IAM_RasterView_F32* p_view)
{
    if (p_view && (*p_view)) {
        free(*p_view);
        *p_view = NULL;
    }
}

float IAM_RasterView_getValue_F32(const IAM_RasterView_F32 view, size_t xid, size_t yid)
{
    size_t ind = xid + yid * view->m_size_x;
    return view->m_pdata[ind];
}

void IAM_RasterView_setValue_F32(IAM_RasterView_F32 view, size_t xid, size_t yid, float value)
{
    size_t ind = xid + yid * view->m_size_x;
    view->m_pdata[ind] = value;
}

bool IAM_RasterView_isNodata_F32(const IAM_RasterView_F32 view, float value)
{
    if (isnan(value)) {
        return true;
    }
    if (isnan(view->m_nodata)) {
        return isnan(value);
    }
    return view->m_nodata == value;
}

/**
 * @brief Float64 栅格视角对象
 * 
 */
IAM_RasterView_F64 IAM_RasterView_init0_F64(void)
{
    IAM_RasterView_F64 view = malloc(sizeof(_IAM_RasterView_F64));
    view->m_size_x = 0;
    view->m_size_y = 0;
    view->m_pdata = NULL;
    view->m_nodata = nan("");
    return view;
}

IAM_RasterView_F64 IAM_RasterView_init_F64(size_t size_x, size_t size_y, double* pdata)
{
    IAM_RasterView_F64 view = malloc(sizeof(_IAM_RasterView_F64));
    view->m_size_x = size_x;
    view->m_size_y = size_y;
    view->m_pdata = pdata;
    view->m_nodata = nan("");
    return view;
}

void IAM_RasterView_reset_F64(IAM_RasterView_F64 view, size_t size_x, size_t size_y, double * pdata)
{
    view->m_size_x = size_x;
    view->m_size_y = size_y;
    view->m_pdata = pdata;
    view->m_nodata = nan("");
}

void IAM_RasterView_release_F64(IAM_RasterView_F64* p_view)
{
    if (p_view && (*p_view)) {
        free(*p_view);
        *p_view = NULL;
    }
}

double IAM_RasterView_getValue_F64(const IAM_RasterView_F64 view, size_t xid, size_t yid)
{
    size_t ind = xid + yid * view->m_size_x;
    return view->m_pdata[ind];
}

void IAM_RasterView_setValue_F64(IAM_RasterView_F64 view, size_t xid, size_t yid, double value)
{
    size_t ind = xid + yid * view->m_size_x;
    view->m_pdata[ind] = value;
}

bool IAM_RasterView_isNodata_F64(const IAM_RasterView_F64 view, double value)
{
    if (isnan(value)) {
        return true;
    }
    if (isnan(view->m_nodata)) {
        return isnan(value);
    }
    return view->m_nodata == value;
}

/**
 * @brief Complex Float32 栅格视角对象
 * 
 */
IAM_RasterView_CF32 IAM_RasterView_init0_CF32(void)
{
    IAM_RasterView_CF32 view = malloc(sizeof(_IAM_RasterView_CF32));
    view->m_size_x = 0;
    view->m_size_y = 0;
    view->m_pdata = NULL;
    view->m_nodata.real = nanf("");
    view->m_nodata.imag = nanf("");
    return view;
}

IAM_RasterView_CF32 IAM_RasterView_init_CF32(size_t size_x, size_t size_y, CpxFloat* pdata)
{
    IAM_RasterView_CF32 view = malloc(sizeof(_IAM_RasterView_CF32));
    view->m_size_x = size_x;
    view->m_size_y = size_y;
    view->m_pdata = pdata;
    view->m_nodata.real = nanf("");
    view->m_nodata.imag = nanf("");
    return view;
}

void IAM_RasterView_reset_CF32(IAM_RasterView_CF32 view, size_t size_x, size_t size_y, CpxFloat * pdata)
{
    view->m_size_x = size_x;
    view->m_size_y = size_y;
    view->m_pdata = pdata;
    view->m_nodata.real = nanf("");
    view->m_nodata.imag = nanf("");
}

void IAM_RasterView_release_CF32(IAM_RasterView_CF32* p_view)
{
    if (p_view && (*p_view)) {
        free(*p_view);
        *p_view = NULL;
    }
}

CpxFloat IAM_RasterView_getValue_CF32(const IAM_RasterView_CF32 view, size_t xid, size_t yid)
{
    size_t ind = xid + yid * view->m_size_x;
    return view->m_pdata[ind];
}

void IAM_RasterView_setValue_CF32(IAM_RasterView_CF32 view, size_t xid, size_t yid, CpxFloat value)
{
    size_t ind = xid + yid * view->m_size_x;
    view->m_pdata[ind] = value;
}

bool IAM_RasterView_isNodata_CF32(const IAM_RasterView_CF32 view, CpxFloat value)
{
    if (isnan(value.real) || isnan(value.imag)) {
        return true;
    }
    if (isnan(view->m_nodata.imag) || isnan(view->m_nodata.real)) {
        return isnan(value.imag) || isnan(value.real);
    }
    return view->m_nodata.imag == value.imag && view->m_nodata.real == value.real;
}


/**
 * @brief Complex Float64 栅格视角对象
 * 
 */
IAM_RasterView_CF64 IAM_RasterView_init0_CF64(void)
{
    IAM_RasterView_CF64 view = malloc(sizeof(_IAM_RasterView_CF64));
    view->m_size_x = 0;
    view->m_size_y = 0;
    view->m_pdata = NULL;
    view->m_nodata.real = nanf("");
    view->m_nodata.imag = nanf("");
    return view;
}

IAM_RasterView_CF64 IAM_RasterView_init_CF64(size_t size_x, size_t size_y, CpxDouble* pdata)
{
    IAM_RasterView_CF64 view = malloc(sizeof(_IAM_RasterView_CF64));
    view->m_size_x = size_x;
    view->m_size_y = size_y;
    view->m_pdata = pdata;
    view->m_nodata.real = nanf("");
    view->m_nodata.imag = nanf("");
    return view;
}

void IAM_RasterView_reset_CF64(IAM_RasterView_CF64 view, size_t size_x, size_t size_y, CpxDouble * pdata)
{
    view->m_size_x = size_x;
    view->m_size_y = size_y;
    view->m_pdata = pdata;
    view->m_nodata.real = nanf("");
    view->m_nodata.imag = nanf("");
}

void IAM_RasterView_release_CF64(IAM_RasterView_CF64* p_view)
{
    if (p_view && (*p_view)) {
        free(*p_view);
        *p_view = NULL;
    }
}

CpxDouble IAM_RasterView_getValue_CF64(const IAM_RasterView_CF64 view, size_t xid, size_t yid)
{
    size_t ind = xid + yid * view->m_size_x;
    return view->m_pdata[ind];
}

void IAM_RasterView_setValue_CF64(IAM_RasterView_CF64 view, size_t xid, size_t yid, CpxDouble value)
{
    size_t ind = xid + yid * view->m_size_x;
    view->m_pdata[ind] = value;
}

bool IAM_RasterView_isNodata_CF64(const IAM_RasterView_CF64 view, CpxDouble value)
{
    if (isnan(value.real) || isnan(value.imag)) {
        return true;
    }
    if (isnan(view->m_nodata.imag) || isnan(view->m_nodata.real)) {
        return isnan(value.imag) || isnan(value.real);
    }
    return view->m_nodata.imag == value.imag && view->m_nodata.real == value.real;
}
